package kercar.xmltools;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import kercar.gps.GPSPosition;

import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class RouteRequester {
	
	/**
	 * Make a request to obtain the route between origin and destination
	 * 
	 * @param origin
	 * @param destination
	 * @return
	 * @throws Exception
	 */
	private static StringBuffer getXMLRoute(GPSPosition origin, GPSPosition destination) throws Exception {
		StringBuffer xmlFile = new StringBuffer();

		URL request = new URL("http://maps.google.com/maps/api/directions/xml?origin=" + origin.getLatitude() + "," + origin.getLongitude() + "&destination=" + destination.getLatitude() + "," + destination.getLongitude() + "&sensor=false&mode=driving");
		BufferedReader in = new BufferedReader(new InputStreamReader(request.openStream()));

		String inputLine;
		while ((inputLine = in.readLine()) != null)
			xmlFile.append(inputLine);
		in.close();

		return xmlFile;
	}

	/**
	 * Parse a XML file to obtain the list of checkpoint on the route
	 * 
	 * @param origin
	 * @param destination
	 * @return
	 */
	public static List<GPSPosition> getRoute(GPSPosition origin, GPSPosition destination) {
		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();

		List<GPSPosition> waypoints = new ArrayList<GPSPosition>();

		try {
			// Acquire the XML file which represent the route
			InputSource inputXml = new InputSource(new StringReader(getXMLRoute(origin, destination).toString()));

			// Acquire the nodes from the polypoints in the xml file
			NodeList nodes = (NodeList) xpath.evaluate("(//points)[not(position()=last())]", inputXml, XPathConstants.NODESET);
		
			//Add the points from the first polypoints in the list
			for (int i = 0, n = nodes.getLength()-1; i < n; i++) {
				String nodeString = nodes.item(i).getTextContent();
				List<GPSPosition> fromPolyPoint = polyPoints.decodePoly(nodeString);
				
				//Remove the last point which will be the first of the next polypoint
				fromPolyPoint.remove(fromPolyPoint.size()-1);
				
				waypoints.addAll(fromPolyPoint);
			}
			
			//Add the points from the last polypoint in the list
			String nodeString = nodes.item(nodes.getLength()-1).getTextContent();
			List<GPSPosition> fromPolyPoint = polyPoints.decodePoly(nodeString);
			waypoints.addAll(fromPolyPoint);
			
			
			

		} catch (XPathExpressionException ex) {
			System.out.print("XPath Error");
		} catch (FileNotFoundException ex) {
			System.out.print("File Error");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return waypoints;
	}
}